package org.front.client.widget.beneficewidget;

import java.util.ArrayList;
import java.util.List;

import org.front.client.service.DistributeurService;
import org.front.client.service.DistributeurServiceAsync;
import org.front.client.widget.beneficewidget.event.BeneficeWidgetEvent;
import org.front.client.widget.beneficewidget.event.BeneficeWidgetHandler;
import org.front.client.widget.mainwidget.i18n.images.MainWidgetImages;
import org.front.shared.data.GraphData;
import org.front.shared.wrap.StatistiqueRequest;
import org.front.shared.wrap.StatistiqueResponse;
import org.front.shared.wrap.TypeStatistique;

import ca.nanometrics.gflot.client.Axis;
import ca.nanometrics.gflot.client.DataPoint;
import ca.nanometrics.gflot.client.PlotModel;
import ca.nanometrics.gflot.client.PlotModelStrategy;
import ca.nanometrics.gflot.client.PlotWithInteractiveLegend;
import ca.nanometrics.gflot.client.SeriesHandler;
import ca.nanometrics.gflot.client.SimplePlot;
import ca.nanometrics.gflot.client.options.AxisOptions;
import ca.nanometrics.gflot.client.options.BarSeriesOptions;
import ca.nanometrics.gflot.client.options.BarSeriesOptions.BarAlignment;
import ca.nanometrics.gflot.client.options.LegendOptions;
import ca.nanometrics.gflot.client.options.LineSeriesOptions;
import ca.nanometrics.gflot.client.options.PlotOptions;
import ca.nanometrics.gflot.client.options.PointsSeriesOptions;
import ca.nanometrics.gflot.client.options.TickFormatter;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.corechart.BarChart;
import com.google.gwt.visualization.client.visualizations.corechart.ColumnChart;
import com.google.gwt.visualization.client.visualizations.corechart.Options;

public class BeneficeWidget extends Composite implements BeneficeWidgetHandler {

	private final DistributeurServiceAsync distributeurService = GWT.create(DistributeurService.class);

	Grid gridBenefice;

	/** UIBinder bindings */
	@UiField
	FlowPanel rootPanel;
	@UiField
	FlowPanel loading;
	@UiField
	FlowPanel panelBenefice;

	private List<GraphData> listStatistiqueMois;

	/** event bus on which to commit */
	private final EventBus eventBus;

	/** Handlers the widget registers */
	private final List<HandlerRegistration> handlersRegistration;

	private static final String[] NOM_MOIS = { "jan", "fev", "mar", "avr", "mai", "jun", "jul", "aou", "sep", "oct", "nov", "dec" };

	/**
	 * Client Bundle resources for this widget
	 */
	public interface Resources extends ClientBundle {

		/** Instance */
		public Resources INSTANCE = GWT.create(Resources.class);

		/**
		 * @return Css
		 */
		@Source("BeneficeWidget.css")
		BeneficeWidgetCssResources css();

		/**
		 * @return Images du widget
		 */
		MainWidgetImages images();
	}

	/**
	 * Declare UIBinder for this widget
	 */
	@UiTemplate("BeneficeWidget.ui.xml")
	interface MainWidgetUiBinder extends UiBinder<Widget, BeneficeWidget> {
	}

	/** UIBinder for building interface */
	private final MainWidgetUiBinder uiBinder;

	public BeneficeWidget(EventBus eventBus) {

		this.eventBus = eventBus;

		// registration of handlers
		this.handlersRegistration = new ArrayList<HandlerRegistration>();

		// create UI
		this.uiBinder = GWT.create(MainWidgetUiBinder.class);
		initWidget(this.uiBinder.createAndBindUi(this));
		Resources.INSTANCE.css().ensureInjected();
		rootPanel.setStyleName("main");
	}

	public void initialiserData() {
		this.loading.setVisible(true);
		initBenefice();
		
	}

	public void afficherExample() {

		PlotModel model = new PlotModel(PlotModelStrategy.defaultStrategy());
		PlotOptions plotOptions = new PlotOptions();
		plotOptions.setDefaultLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true));
		plotOptions.setDefaultPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true));
		plotOptions.setDefaultShadowSize(0);
		plotOptions.setLegendOptions(new LegendOptions().setShow(false));

		// add tick formatter to the options
		plotOptions.setXAxisOptions(new AxisOptions().setTicks(12).setTickFormatter(new TickFormatter() {
			public String formatTickValue(double tickValue, Axis axis) {
				return NOM_MOIS[(int) (tickValue - 1)];
			}
		}));

		// create a series
		// Note: you need to specified the colors in other for the legend to
		// work properly
		SeriesHandler ottawaSeries = model.addSeries("Ottawa", "#edc240");
		SeriesHandler vancouverSeries = model.addSeries("Vancouver", "#afd8f8");

		// add data
		ottawaSeries.add(new DataPoint(1, -10.5));
		ottawaSeries.add(new DataPoint(2, -8.6));
		ottawaSeries.add(new DataPoint(3, -2.4));
		ottawaSeries.add(new DataPoint(4, 6));
		ottawaSeries.add(new DataPoint(5, 13.6));
		ottawaSeries.add(new DataPoint(6, 18.4));
		ottawaSeries.add(new DataPoint(7, 21));
		ottawaSeries.add(new DataPoint(8, 19.7));
		ottawaSeries.add(new DataPoint(9, 14.7));
		ottawaSeries.add(new DataPoint(10, 8.2));
		ottawaSeries.add(new DataPoint(11, 1.5));
		ottawaSeries.add(new DataPoint(12, -6.6));

		vancouverSeries.add(new DataPoint(1, 4.8));
		vancouverSeries.add(new DataPoint(2, 5.9));
		vancouverSeries.add(new DataPoint(3, 7.6));
		vancouverSeries.add(new DataPoint(4, 10));
		vancouverSeries.add(new DataPoint(5, 13.2));
		vancouverSeries.add(new DataPoint(6, 15.9));
		vancouverSeries.add(new DataPoint(7, 18.1));
		vancouverSeries.add(new DataPoint(8, 18.3));
		vancouverSeries.add(new DataPoint(9, 15.4));
		vancouverSeries.add(new DataPoint(10, 11.1));
		vancouverSeries.add(new DataPoint(11, 7.1));
		vancouverSeries.add(new DataPoint(12, 4.8));

		// create the plot
		SimplePlot plot = new SimplePlot(model, plotOptions);

		// put it on a panel
		FlowPanel panel = new FlowPanel();
		panel.add(new HTML("<p style=\"font-weight: bold; align: center;\">Month Temperatures (Daily Average in &deg;C)</p>"));
		panelBenefice.add(new PlotWithInteractiveLegend(plot));

	}

	private void afficherBeneficeMois() {

		panelBenefice.clear();
		PlotModel model = new PlotModel();
		PlotOptions plotOptions = new PlotOptions();

		BarSeriesOptions barSeriesOptions = new BarSeriesOptions();
		barSeriesOptions.setShow(true);
		barSeriesOptions.setLineWidth(2);
		barSeriesOptions.setBarWidth(0.4);
		barSeriesOptions.setAlignment(BarAlignment.CENTER);
		barSeriesOptions.setFill(true);

		// PointsSeriesOptions pointsSeriesOptions = new PointsSeriesOptions();
		// pointsSeriesOptions.setShow(true);
		// pointsSeriesOptions.setFill(true);
		// pointsSeriesOptions.setRadius(8);

		plotOptions.setDefaultBarsSeriesOptions(barSeriesOptions);
		// plotOptions.setDefaultPointsOptions(pointsSeriesOptions);
		plotOptions.setLegendOptions(new LegendOptions().setShow(false));

		// add tick formatter to the options
		plotOptions.setXAxisOptions(new AxisOptions().setTicks(12).setTickFormatter(new TickFormatter() {
			public String formatTickValue(double tickValue, Axis axis) {
				if (tickValue > 0 && tickValue <= 12) {
					return NOM_MOIS[(int) (tickValue - 1)];
				}
				return "";
			}
		}));

		// create a series
		SeriesHandler handler = model.addSeries("Benefices par mois du distributeur", "blue");

		for (int i = 0; i < listStatistiqueMois.size(); i++) {

			GraphData statistiqueMois = listStatistiqueMois.get(i);

			// add data
			DataPoint dataPoint = new DataPoint(i + 1, statistiqueMois.getSommeBenefice());
			handler.add(dataPoint);
		}

		// create the plot
		SimplePlot plot = new SimplePlot(model, plotOptions);

		// put it on a panel
		FlowPanel panel = new FlowPanel();
		panel.add(plot);
		this.loading.setVisible(false);
		panelBenefice.add(panel);

		afficherExample();
		
		// Create a callback to be called when the visualization API
				// has been loaded.
				Runnable onLoadCallback = new Runnable() {
					public void run() {
						
						// Create a pie chart visualization.
						ColumnChart chart = new ColumnChart(createTable(), createOptions());
						chart.setWidth("100%");
						chart.setHeight("300px");
						panelBenefice.add(chart);
					}
				};

				// Load the visualization api, passing the onLoadCallback to be called
				// when loading is done.
				VisualizationUtils.loadVisualizationApi(onLoadCallback, BarChart.PACKAGE);
	}

	/**
	 * 
	 */
	private void initBenefice() {

		if (listStatistiqueMois == null) {
			GWT.log("getStatistique...");
			StatistiqueRequest request = new StatistiqueRequest();

			DateTimeFormat dateFormat = DateTimeFormat.getFormat("dd/MM/yyyy");
			request.setDateDebut(dateFormat.parse("01/01/2011"));
			request.setDateFin(dateFormat.parse("31/12/2011"));

			request.setTypeStatistique(TypeStatistique.BENEFICE_PAR_MOIS);

			distributeurService.getStatistique(request, new AsyncCallback<StatistiqueResponse>() {

				@Override
				public void onSuccess(StatistiqueResponse response) {
					GWT.log("Success : getStatistique");
					populateData(response);
				}

				@Override
				public void onFailure(Throwable caught) {
					GWT.log("Failure : getStatistique " + caught);
				}
			});
		} else {
			afficherBeneficeMois();
		}
	}

	/**
	 * Recuperation du distributeur et appel a l'affichage des blocs
	 * 
	 * @param result
	 */
	private void populateData(StatistiqueResponse response) {
		listStatistiqueMois = response.getListStatistiqueMois();
		afficherBeneficeMois();
	}

	@Override
	protected void onLoad() {
		super.onLoad();
		bind();
	}

	@Override
	protected void onUnload() {
		super.onUnload();
		unbind();
	}

	/**
	 * Bind handler
	 */
	protected void bind() {
		this.handlersRegistration.add(this.eventBus.addHandler(BeneficeWidgetEvent.TYPE, this));
	}

	/**
	 * Unbing handler
	 */
	protected void unbind() {
		// remove handlers registration
		for (final HandlerRegistration hr : this.handlersRegistration) {
			hr.removeHandler();
		}
		this.handlersRegistration.clear();
	}

	@Override
	public void onMainWidget(BeneficeWidgetEvent event) {
		// TODO Auto-generated method stub

	}

	private Options createOptions() {
		Options options = Options.create();
		//options.setWidth(600);
		//options.setHeight(240);
		//options.set3D(true);
		//options.setTitle("My Daily Activities");
		return options;
	}	

	private AbstractDataTable createTable() {
		
		
		DataTable data = DataTable.create();
		data.addColumn(ColumnType.STRING, "Mois");
		data.addColumn(ColumnType.NUMBER, "Benefices");
		data.addRows(12);
		
		for (int i = 0 ; i < listStatistiqueMois.size(); i++) {			
				GWT.log("i = " +i);
				data.setValue(i, 0, NOM_MOIS[i]);
				data.setValue(i, 1, listStatistiqueMois.get(i).getSommeBenefice());			
		}
		/*
		data.setValue(0, 0, NOM_MOIS[0]);
		data.setValue(0, 1, listStatistiqueMois.get(0).getSommeBenefice());
		data.setValue(1, 0, NOM_MOIS[1]);
		data.setValue(1, 1, listStatistiqueMois.get(1).getSommeBenefice());
		data.setValue(2, 0, NOM_MOIS[2]);
		data.setValue(2, 1, listStatistiqueMois.get(2).getSommeBenefice());
		data.setValue(3, 0, NOM_MOIS[3]);
		data.setValue(3, 1, listStatistiqueMois.get(3).getSommeBenefice());
		data.setValue(4, 0, NOM_MOIS[4]);
		data.setValue(4, 1, listStatistiqueMois.get(4).getSommeBenefice());
		data.setValue(5, 0, NOM_MOIS[5]);
		data.setValue(5, 1, listStatistiqueMois.get(5).getSommeBenefice());
		data.setValue(6, 0, NOM_MOIS[6]);
		data.setValue(6, 1, listStatistiqueMois.get(6).getSommeBenefice());
		data.setValue(7, 0, NOM_MOIS[7]);
		data.setValue(7, 1, listStatistiqueMois.get(7).getSommeBenefice());
		data.setValue(8, 0, NOM_MOIS[8]);
		data.setValue(8, 1, listStatistiqueMois.get(8).getSommeBenefice());
		data.setValue(9, 0, NOM_MOIS[9]);
		data.setValue(9, 1, listStatistiqueMois.get(9).getSommeBenefice());
		data.setValue(10, 0, NOM_MOIS[10]);
		data.setValue(10, 1, listStatistiqueMois.get(10).getSommeBenefice());
		data.setValue(11, 0, NOM_MOIS[11]);
		data.setValue(11, 1, listStatistiqueMois.get(11).getSommeBenefice());
		*/
		
		
		return data;
	}

}
